package com.rest.common.utils

import com.google.common.io.ByteStreams
import com.rest.common.Exception.CommonServerException
import com.rest.common.config.InitializeApplication
import org.apache.commons.fileupload.servlet.ServletFileUpload
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.multipart.MultipartFile
import org.springframework.web.multipart.MultipartHttpServletRequest
import java.io.*
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

object FileUtils {
    var logger:Logger = LoggerFactory.getLogger(FileUtils::class.java)

    const val FILE_IMAGE:String = "images"

    fun commonFileUpload(request:HttpServletRequest,filePath:String,maxSize:Long,isChangeOriginFileName:Boolean,allowFileTypes:List<String>):List<String>?{
        if(!ServletFileUpload.isMultipartContent(request))return null
        var filePathList:MutableList<String> = arrayListOf()
        val saveUrl = request.contextPath+File.separator+filePath+File.separator
        var fileFullPath:String = InitializeApplication.BASE_FILE_PATH+saveUrl
        this.validateSavePath(fileFullPath)
        val multipartRequest = request as MultipartHttpServletRequest
        val item = multipartRequest.fileNames
        while (item.hasNext()) {
            val files:List<MultipartFile> = multipartRequest.getFiles(item.next())
            files
            files.forEach {
                this.validateFile(it,maxSize,allowFileTypes)
                val fileExt = it.originalFilename.substring(it.originalFilename.lastIndexOf(".") + 1).toLowerCase()
                var newFileName:String = SimpleDateFormat("yyyyMMddHHmmssSSS").format(Date())+"_"+Random().nextInt()+ "." +fileExt
                if(!isChangeOriginFileName)newFileName=it.originalFilename
                val uploadedFile:File = File(fileFullPath, newFileName)
                ByteStreams.copy(it.inputStream, FileOutputStream(uploadedFile))
                logger.info("上传文件成功:"+uploadedFile.absolutePath)
                filePathList.add(saveUrl+newFileName)
            }
        }
        return filePathList
    }


    private fun validateSavePath(fullPath:String):Unit{
        var file:File = File(fullPath)
        if(!file.canWrite())throw CommonServerException("$fullPath 没有写入权限")
        if(!file.exists()){
            file.mkdir()
        }
    }

    private fun validateFile(file:MultipartFile,maxSize:Long,allowFileTypes:List<String>):Unit{
        maxSize.let {
            if(file.size>maxSize){
                throw CommonServerException("上传文件大小超过限制,maxSize="+maxSize)
            }
        }
        val fileExt = file.originalFilename.substring(file.originalFilename.lastIndexOf(".") + 1).toLowerCase()
        allowFileTypes.let {
            if(!allowFileTypes.contains(fileExt)) {
                throw CommonServerException("文件类型不正确!")
            }
        }
    }


    fun downloadFile(response: HttpServletResponse,filePath:String):Unit{
        val fileFullPath:String = InitializeApplication.BASE_FILE_PATH+File.separator+filePath
        val file:File = File(fileFullPath)
        file
        var out:OutputStream = response.outputStream
        response.contentType="multipart/form-data"
        response.setHeader("Content-Disposition", "attachment;fileName=" + file.name)
        response.setContentLengthLong(file.length())
        var inputStream:InputStream = FileInputStream(file)
        var b = -1
        while (true ){
            out.write(b)
            b = inputStream.read()
            if(b == -1)break
        }
        out.close()
        inputStream.close()
    }


}